main {
   var status = 0;
   thisOplModel.generate();
   // This is an epsilon value to check if reduced cost is strictly negative
   var RC_EPS = 1.0e-6;
   
   // Retrieving model definition, engine and data elements from this OPL model
   // to reuse them later
   var masterDef = thisOplModel.modelDefinition;
   var masterCplex = cplex;
   var masterData = thisOplModel.dataElements;   
   
   // Creating the master-model
   var masterOpl = new IloOplModel(masterDef, masterCplex);
   masterOpl.addDataSource(masterData);
   masterOpl.generate();
   
   // Preparing sub-model source, definition and engine
   var subSource = new IloOplModelSource("cutstock-sub.mod");
   var subDef = new IloOplModelDefinition(subSource);
   var subCplex = new IloCplex();
   
   var best;
   var curr = Infinity;

   while ( best != curr ) {
      best = curr;
      writeln("Solve master.");
      if ( masterCplex.solve() ) {
        masterOpl.postProcess();
        curr = masterCplex.getObjValue();
        writeln();
        writeln("MASTER OBJECTIVE: ",curr);
      } else {
         writeln("No solution to master problem!");
         masterOpl.end();
         break;
      }
      // Ceating the sub model
      var subOpl = new IloOplModel(subDef,subCplex);
      
      // Using data elements from the master model.
      var subData = new IloOplDataElements();
      subData.RollWidth = masterOpl.RollWidth;
      subData.Size = masterOpl.Size;
      subData.Duals = masterOpl.Duals;     
      subOpl.addDataSource(subData); 
      subOpl.generate();
      
      // Previous master model is not needed anymore.
      masterOpl.end();
      
      writeln("Solve sub.");
      if ( subCplex.solve() &&
           subCplex.getObjValue() <= -RC_EPS) {
        writeln();
        writeln("SUB OBJECTIVE: ",subCplex.getObjValue());
      } else {
        writeln("No new good pattern, stop.");
           subData.end();
        subOpl.end();         
        break;
      }
      // prepare next iteration
      masterData.Patterns.add(masterData.Patterns.size,1,subOpl.Use.solutionValue);
      masterOpl = new IloOplModel(masterDef,masterCplex);
      masterOpl.addDataSource(masterData);
      masterOpl.generate();
      // End sub model
         subData.end();
      subOpl.end();      
   }
    
   // Check solution value
   if (Math.abs(curr - 46.25)>=0.0001) {
      status = -1;
      writeln("Unexpected objective value");
   }         

   subDef.end();
   subCplex.end();
   subSource.end();
   
   status;
}